home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / System 7.0 Samples / DTS.Utilities / Utilities.c next >
Encoding:
C/C++ Source or Header  |  1994-11-18  |  47.0 KB  |  1,693 lines  |  [TEXT/MPS ]

  1. /*-----------------------------------------------------------------------------------------
  2. #
  3. #    Apple Macintosh Developer Technical Support
  4. #
  5. #    Collection of Utilities for DTS Sample code
  6. #
  7. #    Program:    Utilities.c.o
  8. #    File:        Utilities.c    -    C Source
  9. #
  10. #    Copyright © 1988-1990 Apple Computer, Inc.
  11. #    All rights reserved.
  12. #
  13. -----------------------------------------------------------------------------------------*/
  14.  
  15. #ifndef __CONTROLS__
  16. #include <Controls.h>
  17. #endif
  18.  
  19. #ifndef __DEVICES__
  20. #include <Devices.h>
  21. #endif
  22.  
  23. #ifndef __EVENTS__
  24. #include <Events.h>
  25. #endif
  26.  
  27. #ifndef __FIXMATH__
  28. #include <FixMath.h>
  29. #endif
  30.  
  31. #ifndef __FONTS__
  32. #include <Fonts.h>
  33. #endif
  34.  
  35. #ifndef __MENUS__
  36. #include <Menus.h>
  37. #endif
  38.  
  39. #ifndef __PACKAGES__
  40. #include <Packages.h>
  41. #endif
  42.  
  43. #ifndef __RESOURCES__
  44. #include <Resources.h>
  45. #endif
  46.  
  47. #ifndef __SCRIPT__
  48. #include <Script.h>
  49. #endif
  50.  
  51. #ifndef __SEGLOAD__
  52. #include <SegLoad.h>
  53. #endif
  54.  
  55. #ifndef __STRING__
  56. #include <String.h>
  57. #endif
  58.  
  59. #ifndef __LOWMEM__
  60. #include <LowMem.h>
  61. #endif
  62.  
  63. #ifndef __TEXTEDIT__
  64. #include <TextEdit.h>
  65. #endif
  66.  
  67. #ifndef __TOOLUTILS__
  68. #include <ToolUtils.h>
  69. #endif
  70.  
  71. #ifndef __TRAPS__
  72. #include <Traps.h>
  73. #endif
  74.  
  75. #ifndef __ERRORS__
  76. #include <Errors.h>
  77. #endif
  78.  
  79. #include "Utilities.h"
  80.  
  81. /*-----------------------------------------------------------------------------------------
  82.     Private Functions 
  83. -----------------------------------------------------------------------------------------*/
  84.  
  85.  
  86.  
  87. /*-----------------------------------------------------------------------------------------
  88.     Global variables -- See Utilities.h for more explanation
  89. -----------------------------------------------------------------------------------------*/
  90. short            gMachineType;            /* which machine this is */
  91. short            gSystemVersion;            /* System version number */
  92. short            gProcessorType;            /* which CPU this is */
  93. Boolean            gHasFPU;                /* true if machine has an FPU */
  94. short            gQDVersion;                /* major QD version #; 0 for original, 
  95.                                                     1 for color QD, 2 for 32-bit QD */
  96. short            gKeyboardType;            /* which type of keyboard is present */
  97. short            gAppleTalkVersion;        /* AppleTalk version number */
  98. Boolean            gHasPMMU;                /* true if machine has a PMMU or equivalent */
  99. short            gAUXVersion;            /* major A/UX version number (0 if not present) */
  100.  
  101. Boolean            gHasWaitNextEvent;
  102. short            gAppResRef;
  103. Boolean            gInBackground;
  104. Str255            gAppName;
  105. OSType            gSignature = '????';
  106. Boolean            gUtilitiesInited;
  107.  
  108.  
  109.  
  110.  
  111. /*****************************************************************************/
  112.  
  113.  
  114.  
  115. /* Given an alert ID and a window pointer the alert relates to, this function
  116. ** will center the alert’s rectangle before showing it on the proper screen.
  117. ** This follows the Apple Human Interface Guidelines for where to place a
  118. ** centered window on the screen.  If the alert is not closely associated with
  119. ** another window, pass a NULL for the window pointer of the related window.  If
  120. ** you pass a NULL, the alert is simply displayed where the resource
  121. ** would indicate.  Note that if an error occurs when getting the resource for
  122. ** the alert, then the alert is not displayed, and the returned value is not
  123. ** the item hit, but is the error that occured when reading the resource. */
  124.  
  125. #pragma segment UtilMain
  126. short    CenteredAlert(short alertID, WindowPtr relatedWindow)
  127. {
  128.     AlertTHndl    alertHandle;
  129.     WindowPtr    tempWindow;
  130.     Rect        alertRect;
  131.     short        itemHit;
  132.     char        hstate;
  133.     OSErr        err;
  134.     
  135.     alertHandle = (AlertTHndl)GetAppResource('ALRT', alertID, &err);
  136.     if (err) return((short)err);
  137.  
  138.     hstate = LockHandleHigh((Handle)alertHandle);
  139.         /* Do our part to help prevent fragmentation. */
  140.  
  141.     alertRect = (*alertHandle)->boundsRect;
  142.         /* Preserve the real alert bounding rectangle. */
  143.  
  144.     if (tempWindow = NewWindow(NULL, &alertRect, '', false, dBoxProc,
  145.                               (WindowPtr)NULL, false, 0)) {
  146.         /* Use an invisible temporary window to calculate where the alert will go. */
  147.  
  148.         (*alertHandle)->boundsRect = CenterWindow(tempWindow, relatedWindow);
  149.         DisposeWindow(tempWindow);
  150.     }
  151.  
  152.     itemHit = Alert(alertID, (ModalFilterProcPtr)NULL);
  153.  
  154.     (*alertHandle)->boundsRect = alertRect;
  155.         /* Restore the resource's bounding rect, so if this resource is ever used
  156.         ** not through this function, it will open where the resource indicates. */
  157.  
  158.     HSetState((Handle)alertHandle, hstate);
  159.     return(itemHit);
  160. }
  161.  
  162.  
  163.  
  164. /*****************************************************************************/
  165.  
  166.  
  167.  
  168. /* Given two rects, this function centers the second one within the first. */
  169.  
  170. #pragma segment UtilMain
  171. void    CenterRectInRect(Rect outerRect, Rect *innerRect)
  172. {
  173.     PositionRectInRect(outerRect, innerRect, FixRatio(1, 2), FixRatio(1, 2));
  174. }
  175.  
  176.  
  177.  
  178. /*****************************************************************************/
  179.  
  180.  
  181.  
  182. /* Center a window within a particular device.  The device to center the window
  183. ** within is determined by passing a related window.  This allows related
  184. ** windows to be kept on the same device.  This is useful if an alert related
  185. ** to a specific window, for example. */
  186.  
  187. #pragma segment UtilMain
  188. Rect    CenterWindow(WindowPtr window, WindowPtr relatedWindow)
  189. {
  190.     WindowPtr    whichDevice;
  191.     Rect        deviceRect, oldWindowRect, newWindowRect, contentRect;
  192.  
  193.     if (!(whichDevice = relatedWindow)) whichDevice = window;
  194.         /* If we have a window to center against, use the device for that window,
  195.         ** else use the device for the window that is getting centered. */
  196.  
  197.     deviceRect = GetWindowDeviceRectNMB(whichDevice);
  198.         /* We now have the rectangle of the device we want to center within. */
  199.  
  200.     oldWindowRect = newWindowRect = GetWindowStructureRect(window);
  201.  
  202.     PositionRectInRect(deviceRect, &newWindowRect, FixRatio (1, 2),
  203.                        FixRatio (1, 3));
  204.         /* Figure out the new window strucRect so we can compare it against
  205.         ** the old strucRect.  This will tell us how much to move the window. */
  206.  
  207.     contentRect = GetWindowContentRect(window);
  208.         /* Get where the window is now. */
  209.  
  210.     OffsetRect(&contentRect, newWindowRect.left - oldWindowRect.left,
  211.                             newWindowRect.top  - oldWindowRect.top);
  212.         /* Calculate the new content rect. */
  213.  
  214.     MoveWindow(window, contentRect.left, contentRect.top, false);
  215.         /* Move the window to the new location. */
  216.  
  217.     return(contentRect);
  218. }
  219.  
  220.  
  221.  
  222. /*****************************************************************************/
  223.  
  224.  
  225.  
  226. /* Close a window.  This handles desk accessory and application windows.  Use
  227. ** this call (instead of DisposeAnyWindow) if the memory for the window was
  228. ** allocated by you.  (Same as CloseWindow v.s. DisposeWindow.) */
  229.  
  230. #pragma segment UtilMain
  231. void    CloseAnyWindow(WindowPtr window)
  232. {
  233.     if (IsDAWindow(window))
  234.         CloseDeskAcc(((WindowPeek)window)->windowKind);
  235.     else {
  236.         if (IsAppWindow(window))
  237.             CloseWindow(window);
  238.         else if (((WindowPeek)window)->windowKind >= dialogKind)
  239.             CloseDialog((DialogPtr)window);
  240.     }
  241. }
  242.  
  243.  
  244.  
  245. /*****************************************************************************/
  246.  
  247.  
  248.  
  249. /* Dispose a window.  This handles desk accessory and application windows.  Use
  250. ** this call (instead of CloseAnyWindow) if you want the memory for the window
  251. ** record to be disposed of.  (Same as CloseWindow v.s. DisposeWindow.) */
  252.  
  253. #pragma segment UtilMain
  254. void    DisposeAnyWindow(WindowPtr window)
  255. {
  256.     if (IsDAWindow(window))
  257.         CloseDeskAcc(((WindowPeek)window)->windowKind);
  258.     else {
  259.         if (IsAppWindow(window))
  260.             DisposeWindow(window);
  261.         else if (((WindowPeek)window)->windowKind >= dialogKind)
  262.             DisposeDialog((DialogPtr)window);
  263.     }
  264. }
  265.  
  266.  
  267.  
  268. /*****************************************************************************/
  269.  
  270.  
  271.  
  272. /* Display an alert that tells the user an error occurred, then exit the
  273. ** program.  This function is used as an ultimate bail-out for serious errors
  274. ** that prohibit the continuation of the application.  Errors that do not
  275. ** require the termination of the application should be handled in a different
  276. ** manner. */  
  277.  
  278. #pragma segment UtilMain
  279. void    DeathAlert(short errResID, short errStringIndex)
  280. {
  281.     ErrorAlert(errResID, errStringIndex);
  282.     ExitToShell();
  283. }
  284.  
  285.  
  286.  
  287. /*****************************************************************************/
  288.  
  289.  
  290.  
  291. /* Display an alert that tells the user an error occurred, then exit the
  292. ** program.  This function is used as an ultimate bail-out for serious errors
  293. ** that prohibit the continuation of the application.  Errors that do not
  294. ** require the termination of the application should be handled in a different
  295. ** manner.  The message parameter is an error code that is to be displayed. */
  296.  
  297. #pragma segment UtilMain
  298. void    DeathAlertMessage(short errResID, short errStringIndex, short message)
  299. {
  300.     ErrorAlertMessage(errResID, errStringIndex, message);
  301.     ExitToShell();
  302. }
  303.  
  304.  
  305.  
  306. /*****************************************************************************/
  307.  
  308.  
  309.  
  310. /* Display an alert that tells the user an error occurred. */
  311.  
  312. #pragma segment UtilMain
  313. void    ErrorAlert(short errResID, short errStringIndex)
  314. {
  315.     ErrorAlertMessage(errResID, errStringIndex, 0);
  316. }
  317.  
  318.  
  319.  
  320. /*****************************************************************************/
  321.  
  322.  
  323.  
  324. /* Display an alert to inform the user of an error.  errStringIndex acts as an
  325. ** index into a STR# resource of error messages.  If no errStringIndex is
  326. ** given, i.e. = 0, then use a standard message.  If message is not noErr then
  327. ** display it as well.
  328. **
  329. ** BUG NOTE:  GetIndString returns a bogus String if the index is
  330. **            not positive. */
  331.   
  332. #pragma segment UtilMain
  333. void    ErrorAlertMessage(short errResID, short errStringIndex, short message)
  334. {
  335.     Str255    msg1, msg2;
  336.  
  337.     SetCursor(&QD(arrow));
  338.  
  339.     if (errStringIndex <= 0) {
  340.         errStringIndex = eStandardErr;
  341.         errResID = rUtilStrings;
  342.     }
  343.     GetIndString(&msg1, errResID, errStringIndex);
  344.  
  345.     if (message == noErr) {
  346.         ParamText(&msg1, '', '', '');
  347.         CenteredAlert(rUtilErrorAlert, NULL);
  348.     } else {
  349.         NumToString(message, (StringPtr)&msg2);
  350.         ParamText(&msg1, &msg2, '', '');
  351.         CenteredAlert(rUtilErrorMessageAlert, NULL);
  352.     }
  353. }
  354.  
  355.  
  356.  
  357. /*****************************************************************************/
  358.  
  359.  
  360.  
  361. /* FindSysFolder returns the (real) vRefNum, and the DirID of the current
  362. ** system folder.  It uses the Folder Manager if present, otherwise it falls
  363. ** back to SysEnvirons.  It returns zero on success, otherwise a standard
  364. ** system error. */
  365.  
  366. #pragma segment UtilMain
  367. OSErr    FindSysFolder(short *foundVRefNum, long *foundDirID)
  368. {
  369.     long            gesResponse;
  370.     SysEnvRec        envRec;
  371.     WDPBRec            myWDPB;
  372.     unsigned char    volName[34];
  373.     OSErr            err;
  374.     
  375.     
  376.     *foundVRefNum = 0;
  377.     *foundDirID = 0;
  378.     if (!Gestalt (gestaltFindFolderAttr, &gesResponse) &&
  379.         BTstQ (gesResponse, gestaltFindFolderPresent)) {    /* Does Folder Manager exist? */
  380.             err = FindFolder (kOnSystemDisk, kSystemFolderType, kDontCreateFolder, 
  381.                 foundVRefNum, foundDirID);
  382.     } else {
  383.         /* Gestalt can't give us the answer, so we resort to SysEnvirons */
  384.         if (!(err = SysEnvirons (curSysEnvVers, &envRec))) {
  385.             myWDPB.ioVRefNum = envRec.sysVRefNum;
  386.             volName[0] = '\000';                    /* Zero volume name */
  387.             myWDPB.ioNamePtr = volName;
  388.             myWDPB.ioWDIndex = 0;
  389.             myWDPB.ioWDProcID = 0;
  390.             if (!(err = PBGetWDInfo (&myWDPB, 0))) {
  391.                 *foundVRefNum = myWDPB.ioWDVRefNum;
  392.                 *foundDirID = myWDPB.ioWDDirID;
  393.             }
  394.         }
  395.     }
  396.     return (err);
  397. }
  398.  
  399.  
  400.  
  401. /*****************************************************************************/
  402.  
  403.  
  404.  
  405. /* GetAppIndResource gets a resource from the application's resource file
  406. ** by index. */
  407.  
  408. #pragma segment UtilMain
  409. Handle    GetAppIndResource(ResType theType, short index, OSErr *err)
  410. {
  411. #pragma unused (err)
  412.  
  413.     short    savedResFile;
  414.     Handle    returnHandle;
  415.     
  416.     savedResFile = CurResFile ();
  417.     UseResFile (gAppResRef);
  418.     returnHandle = Get1IndResource(theType, index);
  419.     UseResFile (savedResFile);
  420.     return (returnHandle);
  421. }
  422.  
  423.  
  424.  
  425. /*****************************************************************************/
  426.  
  427.  
  428.  
  429. /* GetAppNamedResource gets a resource from the application's resource file
  430. ** by name. */
  431.  
  432. #pragma segment UtilMain
  433. Handle    GetAppNamedResource(ResType theType, Str255 name, OSErr *err)
  434. {
  435.     short    savedResFile;
  436.     Handle    returnHandle;
  437.     
  438.     savedResFile = CurResFile ();
  439.     UseResFile (gAppResRef);
  440.     returnHandle = Get1NamedResource(theType, name);
  441.     *err = ResError();
  442.     UseResFile (savedResFile);
  443.     return (returnHandle);
  444. }
  445.  
  446.  
  447.  
  448. /*****************************************************************************/
  449.  
  450.  
  451.  
  452. /* GetAppResource gets a resource from the application's resource file by
  453. ** resource ID. */
  454.  
  455. #pragma segment UtilMain
  456. Handle    GetAppResource(ResType theType,short theID, OSErr *err)
  457. {
  458.     short    savedResFile;
  459.     Handle    returnHandle;
  460.     
  461.     savedResFile = CurResFile ();
  462.     UseResFile (gAppResRef);
  463.     returnHandle = Get1Resource(theType, theID);
  464.     *err = ResError();
  465.     UseResFile (savedResFile);
  466.     return (returnHandle);
  467. }
  468.  
  469.  
  470.  
  471. /*****************************************************************************/
  472.  
  473.  
  474.  
  475. /* Checks for the presence of A/UX by whatever means is appropriate.  Returns
  476. ** the major version number of A/UX (i.e. 0 if A/UX is not present, 1 for
  477. ** any 1.x.x version 2 for any 2.x version, etc.
  478. **
  479. ** This code should work for all past, present and future A/UX systems. */
  480.  
  481. #pragma segment UtilMain
  482. short    GetAUXVersion(void)
  483. {
  484.     long    auxVersion;
  485.     short    err;
  486.     
  487.         /*
  488.      *    This code assumes the Gestalt glue checks for the presence of the _Gestalt
  489.      *    trap and does something intelligent if the trap is unavailable, i.e.
  490.      *    return unknown selector.
  491.      */
  492.     auxVersion = 0;
  493.     err = Gestalt(gestaltAUXVersion, &auxVersion);
  494.     /*
  495.      *    If gestaltUnknownErr or gestaltUndefSelectorErr was returned, then either 
  496.      *    we weren't running on A/UX, or the _Gestalt trap is unavailable so use 
  497.      *    HWCfgFlags instead.
  498.      *    All other errors are ignored (implies A/UX not present).
  499.      */
  500.     if (err == gestaltUnknownErr || err == gestaltUndefSelectorErr) {    /* Use HWCfgFlags */
  501.         if (BTstQ(LMGetHWCfgFlags(), 9))
  502.             auxVersion = 0x100;            /* Do Have A/UX, so assume version 1.x.x */
  503.     }
  504.     /*
  505.      *    Now right shift auxVersion by 8 bits to get major version number
  506.      */
  507.     auxVersion >>= 8;
  508.     return((short)auxVersion);
  509. }
  510.  
  511.  
  512.  
  513. /*****************************************************************************/
  514.  
  515.  
  516.  
  517. /* Given a dialog ID and a window pointer the dialog relates to, this function
  518. ** will center the dialog’s rectangle before showing it on the proper screen.
  519. ** This follows the Apple Human Interface Guidelines for where to place a
  520. ** centered window on the screen.  If the dialog is not closely associated with
  521. ** another window, pass a NULL for the window pointer of the related window.  If
  522. ** you pass a NULL, the dialog is simply displayed where the resource
  523. ** would indicate. */
  524.  
  525. #pragma segment UtilMain
  526. DialogPtr    GetCenteredDialog(short id, DialogPtr storage, WindowPtr relatedWindow, WindowPtr behind)
  527. {
  528.     DialogTHndl        dlogResource;
  529.     DialogPtr        dialog;
  530.     Boolean            oldVis;
  531.     char            hstate;
  532.     OSErr            err;
  533.     
  534.     dialog = NULL;
  535.     if (dlogResource = (DialogTHndl)GetAppResource('DLOG', id, &err)) {
  536.         hstate = LockHandleHigh((Handle)dlogResource);
  537.         oldVis = (*dlogResource)->visible;
  538.         (*dlogResource)->visible = false;
  539.         if (dialog = GetNewDialog(id, storage, behind)) {
  540.             CenterWindow(dialog, relatedWindow);
  541.             if (oldVis) ShowWindow(dialog);
  542.         }
  543.         (*dlogResource)->visible = oldVis;
  544.         HSetState((Handle)dlogResource, hstate);
  545.     }
  546.     return(dialog);
  547. }
  548.  
  549.  
  550.  
  551. /*****************************************************************************/
  552.  
  553.  
  554.  
  555. /* Given a window ID and a window pointer the window relates to, this function
  556. ** will center the window’s rectangle before showing it on the proper screen.
  557. ** This follows the Apple Human Interface Guidelines for where to place a
  558. ** centered window on the screen.  If the window is not closely associated with
  559. ** another window, pass a NULL for the window pointer of the related window.  If
  560. ** you pass a NULL, the window is simply displayed where the resource
  561. ** would indicate. */
  562.  
  563. #pragma segment UtilMain
  564. WindowPtr    GetCenteredWindow(short id, Ptr storage, WindowPtr relatedWindow,
  565.                               WindowPtr behind, Boolean inColor)
  566. {
  567.     return(GetSomeKindOfWindow(CenterWindow, id, storage, relatedWindow, behind, inColor));
  568. }
  569.  
  570.  
  571.  
  572. /*****************************************************************************/
  573.  
  574.  
  575.  
  576. #pragma segment UtilMain
  577. Boolean GetCheckOrRadio(DialogPtr dlgPtr, short itemNo)
  578. {
  579.     short    iKind;
  580.     Handle    iHandle;
  581.     Rect    iRect;
  582.  
  583.     GetDialogItem(dlgPtr, itemNo, &iKind, &iHandle, &iRect);
  584.     return(GetControlValue((ControlHandle)iHandle) != 0);
  585. }
  586.  
  587.  
  588.  
  589. /*****************************************************************************/
  590.  
  591.  
  592.  
  593. /* GetGestaltResult returns the result value from Gestalt for the specified
  594. ** selector.  If Gestalt returned an error GetGestaltResult returns zero.
  595. ** Use of this function is only cool if we don't care whether Gestalt returned
  596. ** an error.  In many cases you may need to know the exact Gestalt error code
  597. ** so then this function would be inappropriate.
  598. ** See GetAUXVersion for an example. */
  599.  
  600. #pragma segment UtilMain
  601. long    GetGestaltResult(OSType gestaltSelector)
  602. {
  603.     long    gestaltResult;
  604.     
  605.     if (Gestalt(gestaltSelector, &gestaltResult) == noErr)
  606.         return(gestaltResult);
  607.     else
  608.         return(0);
  609. }
  610.  
  611.  
  612.  
  613. /*****************************************************************************/
  614.  
  615.  
  616.  
  617. /* Get the global coordinates of the mouse.  When you call OSEventAvail it will
  618. ** return either a pending event or a null event.  In either case, the where
  619. ** field of the event record will contain the current position of the mouse in
  620. ** global coordinates and the modifiers field will reflect the current state of
  621. ** the modifiers.  Another way to get the global coordinates is to call
  622. ** GetMouse and LocalToGlobal, but that requires being sure that thePort is set
  623. ** to a valid port. */
  624.  
  625. #pragma segment UtilMain
  626. Point    GetGlobalMouse(void)
  627. {
  628.     EventRecord    event;
  629.     
  630.     OSEventAvail(kNoEvents, &event);    /* we aren’t interested in any events */
  631.     return(event.where);                /* just the mouse position */
  632. }
  633.  
  634.  
  635.  
  636. /*****************************************************************************/
  637.  
  638.  
  639.  
  640. /* Given a window, this will return the top left point of the window’s port in
  641. ** global coordinates.  Something this doesn’t include is the window’s drag
  642. ** region (or title bar).  This returns the top left point of the window’s
  643. ** content area only. */
  644.   
  645. #pragma segment UtilMain
  646. Point    GetGlobalTopLeft(WindowPtr window)
  647. {
  648.     GrafPtr            oldPort;
  649.     Point            globalPt;
  650.     
  651.     GetPort(&oldPort);
  652.     SetPort(window);
  653.     globalPt = TopLeft(window->portRect);
  654.     LocalToGlobal(&globalPt);
  655.     SetPort(oldPort);
  656.     return(globalPt);
  657. }
  658.  
  659.  
  660.  
  661. /*****************************************************************************/
  662.  
  663.  
  664.  
  665. /* Return the amount of free space on the volume in KBytes. -1 is returned as
  666. ** the size if there is an error. */
  667.  
  668. #pragma segment UtilInit
  669. long    GetKFreeSpace(short vRefNum)
  670. {
  671.     HParamBlockRec    pb;
  672.     OSErr            err;
  673.  
  674.     pb.volumeParam.ioNamePtr = NULL;            /* we don't care about the name */
  675.     pb.volumeParam.ioVRefNum = vRefNum;
  676.     pb.volumeParam.ioVolIndex = 0;            /* use ioVRefNum only */
  677.     err = PBHGetVInfo(&pb, false);
  678.  
  679.     if (err == noErr)
  680.         return((pb.volumeParam.ioVFrBlk * pb.volumeParam.ioVAlBlkSiz) / 1024);
  681.     else
  682.         return(-1);
  683. }
  684.  
  685.  
  686.  
  687. /*****************************************************************************/
  688.  
  689.  
  690.  
  691. #pragma segment UtilMain
  692. Rect    GetMainScreenRect(void)
  693. {
  694.     GDHandle    mainDevice;
  695.     GrafPtr        mainPort;
  696.  
  697.     if (gQDVersion > kQDOriginal) {
  698.         mainDevice = GetMainDevice();
  699.         return((*mainDevice)->gdRect);
  700.     } else {
  701.         GetWMgrPort(&mainPort);
  702.         return(mainPort->portRect);
  703.     }
  704. }
  705.  
  706.  
  707.  
  708. /*****************************************************************************/
  709.  
  710.  
  711.  
  712. /* Find the greatest overlap device for the given global rectangle. */
  713.  
  714. #pragma segment UtilInit
  715. GDHandle    GetRectDevice(Rect globalRect)
  716. {
  717.     long        area;
  718.     long        maxArea;
  719.     GDHandle    device;
  720.     GDHandle    deviceToReturn;
  721.     Rect        intersection;
  722.  
  723.     deviceToReturn = GetMainDevice();            /* Use as default choice. */
  724.     maxArea = 0;
  725.  
  726.     for (device = GetDeviceList(); device; device = GetNextDevice(device)) {
  727.         if (TestDeviceAttribute(device, screenDevice)
  728.           && TestDeviceAttribute(device, screenActive)
  729.           && SectRect(&globalRect, &((*device)->gdRect), &intersection)) {
  730.             area = (intersection.right - intersection.left) *
  731.                    (intersection.bottom - intersection.top);
  732.             if (area > maxArea) {
  733.                 deviceToReturn = device;
  734.                 maxArea = area;
  735.             }
  736.         }
  737.     }
  738.     return(deviceToReturn);
  739. }
  740.  
  741.  
  742.  
  743. /*****************************************************************************/
  744.  
  745.  
  746.  
  747. /* Find the rect of the greatest overlap device for the given global rect. */
  748.  
  749. #pragma segment UtilInit
  750. Rect    GetRectDeviceRect(Rect globalRect)
  751. {
  752.     if (gQDVersion > kQDOriginal)
  753.         return((*GetRectDevice(globalRect))->gdRect);
  754.     else
  755.         return(GetMainScreenRect());
  756. }
  757.  
  758.  
  759.  
  760. /*****************************************************************************/
  761.  
  762.  
  763.  
  764. /* Given a window positioning procedure pointer, a window ID and a window
  765. ** pointer the window relates to, this function open a new window by either
  766. ** a NewCWindow or a NewWindow call, depending on the value of inColor.  The
  767. ** window will be opened invisible, independent of what the resource says.
  768. ** Once the window is opened successfully, the positioning procedure is
  769. ** called.  The positioning procedure is passed a pointer to the just-opened
  770. ** invisible window and a pointer to the related window.  It is up to the
  771. ** positioning procedure to move the invisible window to the correct location
  772. ** on the correct device.  Once the positioning procedure returns, the window
  773. ** will be made visible if so indicated by the resource. */
  774.  
  775. #pragma segment UtilMain
  776. WindowPtr    GetSomeKindOfWindow(PositionWndProcPtr whatKind, short windID,
  777.                                 Ptr storage, WindowPtr relatedWindow,
  778.                                 WindowPtr behind, Boolean inColor)
  779. {
  780.     WindowTHndl        windowResource;
  781.     WindowTemplate    wt;                /* Window template. */
  782.     WindowPtr        aWindow;
  783.     OSErr            err;
  784.  
  785.     if (!gQDVersion) inColor = false;
  786.  
  787.     aWindow = NULL;        /* Assume we will fail.  (Good attitude.) */
  788.  
  789.     if (!storage) storage = NewPtr(sizeof(WindowRecord));
  790.  
  791.     if (storage) {            /* If we have memory for the window record... */
  792.  
  793.         if (windowResource = (WindowTHndl)GetAppResource('WIND', windID, &err)) {
  794.             /* If we can load the window resource... */
  795.  
  796.             wt = **windowResource;        /* Make local copy of resource. */
  797.  
  798.             aWindow = (inColor ? NewCWindow(storage, &wt.boundsRect,
  799.                                             wt.title, false, wt.procID,
  800.                                             behind, wt.goAwayFlag, wt.refCon)
  801.                                : NewWindow(storage, &wt.boundsRect, wt.title,
  802.                                            false, wt.procID,
  803.                                            behind, wt.goAwayFlag, wt.refCon));
  804.                 /* Open either a regular or color window. */
  805.  
  806.             if (aWindow) {        /* If we were able to open a window... */
  807.                 (*whatKind)(aWindow, relatedWindow);
  808.                     /* Call the designated window positioning procedure. */
  809.  
  810.                 if (wt.visible) ShowWindow(aWindow);
  811.                     /* If resource says window should be visible, do it. */
  812.             }
  813.         }
  814.         if (!aWindow) DisposePtr(storage);
  815.             /* If we failed, then get rid of window record memory. */
  816.     }
  817.  
  818.     return(aWindow);
  819. }
  820.  
  821.  
  822.  
  823. /*****************************************************************************/
  824.  
  825.  
  826.  
  827. /* Given a window ID and a window pointer the window relates to, this function
  828. ** will stagger the window’s rectangle before showing it on the proper screen.
  829. ** This follows the Apple Human Interface Guidelines for where to place a
  830. ** staggered window on the screen.  If the window is not closely associated
  831. ** with another window, pass a NULL for the window pointer of the related
  832. ** window.  If you pass a NULL, the window is simply displayed where the
  833. ** resource would indicate. */
  834.  
  835. #pragma segment UtilMain
  836. WindowPtr    GetStaggeredWindow(short id, Ptr storage, WindowPtr relatedWindow,
  837.                                WindowPtr behind, Boolean inColor)
  838. {
  839.     return(GetSomeKindOfWindow(StaggerWindow, id, storage, relatedWindow, behind, inColor));
  840. }
  841.  
  842.  
  843.  
  844. /*****************************************************************************/
  845.  
  846.  
  847.  
  848. /*    Check the bits of a trap number to determine its type. */
  849.  
  850. #pragma segment UtilInit
  851. TrapType    GetTrapType(short theTrap)
  852. {
  853.     /* OS traps start with A0, Tool with A8 or AA. */
  854.     if ((theTrap & 0x0800) == 0)                    /* per D.A. */
  855.         return (OSTrap);
  856.     else
  857.         return (ToolTrap);
  858. }
  859.  
  860.  
  861.  
  862. /*****************************************************************************/
  863.  
  864.  
  865.  
  866. /* Given a window pointer, return the global rectangle that encloses the
  867. ** content area of the window. */
  868.  
  869. #pragma segment UtilMain
  870. Rect    GetWindowContentRect(WindowPtr window)
  871. {
  872.     WindowPtr    oldPort;
  873.     Rect        contentRect;
  874.  
  875.     GetPort(&oldPort);
  876.     SetPort(window);
  877.     contentRect = window->portRect;
  878.     LocalToGlobalRect(&contentRect);
  879.     SetPort(oldPort);
  880.     return(contentRect);
  881. }
  882.  
  883.  
  884.  
  885. /*****************************************************************************/
  886.  
  887.  
  888.  
  889. /* This procedure counts the number of windows in the application plane.
  890. ** You have the choices of also including DAs and invisible windows in
  891. ** this count. */
  892.  
  893. #pragma segment UtilMain
  894. short    GetWindowCount(Boolean includeDAs, Boolean includeInvisibles)
  895. {
  896.     WindowPeek    window;
  897.     short        count;
  898.  
  899.     for (count = 0, window = (WindowPeek)LMGetWindowList();
  900.          (window != NULL); window = window->nextWindow) {
  901.  
  902.         if ((window->windowKind < 0) && (!includeDAs)) continue;
  903.         if ((window->visible) || (includeInvisibles)) count++;
  904.     }
  905.     return (count);
  906. }
  907.  
  908.  
  909.  
  910. /*****************************************************************************/
  911.  
  912.  
  913.  
  914. /* Find the greatest overlap device for the given window. */
  915.  
  916. #pragma segment UtilInit
  917. GDHandle    GetWindowDevice(WindowPtr window)
  918. {
  919.     return(GetRectDevice(GetWindowStructureRect(window)));
  920. }
  921.  
  922.  
  923.  
  924. /*****************************************************************************/
  925.  
  926.  
  927.  
  928. /* Given a window pointer, find the device that contains most of the window
  929. ** and return the device's bounding rectangle. */
  930.  
  931. #pragma segment UtilMain
  932. Rect    GetWindowDeviceRect(WindowPtr window)
  933. {
  934.     if (gQDVersion > kQDOriginal)
  935.         return((*GetWindowDevice(window))->gdRect);
  936.     else
  937.         return(GetMainScreenRect());
  938. }
  939.  
  940.  
  941.  
  942. /*****************************************************************************/
  943.  
  944.  
  945.  
  946. /* Given a window pointer, find the device that contains most of the window
  947. ** and return the device's bounding rectangle.  If this device is the main
  948. ** device, then remove the menubar area from the rectangle. */
  949.  
  950. #pragma segment UtilMain
  951. Rect    GetWindowDeviceRectNMB(WindowPtr window)
  952. {
  953.     Rect        deviceRect, tempRect;
  954.  
  955.     deviceRect = GetWindowDeviceRect(window);
  956.     tempRect = GetMainScreenRect();
  957.     if (EqualRect(&deviceRect, &tempRect)) deviceRect.top += GetMBarHeight();
  958.  
  959.     return(deviceRect);
  960. }
  961.  
  962.  
  963.  
  964. /*****************************************************************************/
  965.  
  966.  
  967.  
  968. /* This procedure is used to get the rectangle that surrounds the entire
  969. ** structure of a window.  This is true whether or not the window is visible.
  970. ** If the window is visible, then it is a simple matter of using the bounding
  971. ** rectangle of the structure region.  If the window is invisible, then the
  972. ** strucRgn is not correct.  To make it correct, then window has to be moved
  973. ** way off the screen and then made visible.  This generates a valid strucRgn,
  974. ** although it is valid for the position that is way off the screen.  It still
  975. ** needs to be offset back into the original position.  Once the bounding
  976. ** rectangle for the strucRgn is obtained, the window can then be hidden again
  977. ** and moved back to its correct location.  Note that ShowHide is used,
  978. ** instead of ShowWindow and HideWindow.  HideWindow can change the plane of
  979. ** the window.  Also, ShowHide does not affect the hiliting of windows. */
  980.  
  981. #pragma segment UtilMain
  982. Rect    GetWindowStructureRect(WindowPtr window)
  983. {
  984. #define kOffscreenLoc 0x4000
  985.  
  986.     GrafPtr        oldPort;
  987.     Rect        structureRect;
  988.     Point        windowLoc;
  989.     
  990.     if (((WindowPeek)window)->visible)
  991.         structureRect = (*(((WindowPeek)window)->strucRgn))->rgnBBox;
  992.  
  993.     else {
  994.         GetPort(&oldPort);
  995.         SetPort(window);
  996.         windowLoc = GetGlobalTopLeft(window);
  997.         MoveWindow(window, windowLoc.h, kOffscreenLoc, false);
  998.         ShowHide(window, true);
  999.         structureRect = (*(((WindowPeek)window)->strucRgn))->rgnBBox;
  1000.         ShowHide(window, false);
  1001.         MoveWindow(window, windowLoc.h, windowLoc.v, false);
  1002.         SetPort(oldPort);
  1003.         OffsetRect(&structureRect, 0, windowLoc.v - kOffscreenLoc);
  1004.     }
  1005.     return(structureRect);
  1006. }
  1007.  
  1008.  
  1009.  
  1010. /*****************************************************************************/
  1011.  
  1012.  
  1013.  
  1014. #pragma segment UtilMain
  1015. void    GlobalToLocalRect(Rect *aRect)
  1016. {
  1017.     GlobalToLocal(&TopLeft(*aRect));
  1018.     GlobalToLocal(&BotRight(*aRect));
  1019. }
  1020.  
  1021.  
  1022.  
  1023. /*****************************************************************************/
  1024.  
  1025.  
  1026.  
  1027. #pragma segment UtilInit
  1028. void    InitToolBox(void)
  1029. {
  1030.     InitGraf((Ptr) &QD(thePort));
  1031.     InitFonts();
  1032.     InitWindows();
  1033.     InitMenus();
  1034.     TEInit();
  1035.     InitDialogs(NULL);
  1036.     InitCursor();
  1037. }
  1038.     
  1039.  
  1040.  
  1041. /*****************************************************************************/
  1042.  
  1043.  
  1044.  
  1045. /* InitUtilities sets up some global variables for use by the utilities
  1046. ** package.  If you call StandardInitialization, you don't need to call this,
  1047. ** as it will do it for you. */ 
  1048.  
  1049. #pragma segment UtilInit
  1050. void    InitUtilities(void)
  1051. {
  1052.     Handle    apParam;
  1053.     Handle    bndlResource;
  1054.     OSErr    err;
  1055.  
  1056.     gUtilitiesInited = false;
  1057.  
  1058.     /* Init all the Gestalt variables */
  1059.     gMachineType = GetGestaltResult (gestaltMachineType);
  1060.     gSystemVersion = GetGestaltResult (gestaltSystemVersion);
  1061.     gProcessorType = GetGestaltResult (gestaltProcessorType);
  1062.  
  1063.     /* We only concern ourselves with there being an FPU, not which type it is */
  1064.     gHasFPU = (GetGestaltResult (gestaltFPUType) != gestaltNoFPU);
  1065.     
  1066.     /*
  1067.      *    We only concern ourselves with the major QD version number
  1068.      *    0 for original QD, 1 for 8-bit color QD, and 2 for 32-bit QD
  1069.      */
  1070.     gQDVersion = (GetGestaltResult (gestaltQuickdrawVersion) >> 8) & 0xFF;
  1071.     gKeyboardType = GetGestaltResult (gestaltKeyboardType);
  1072.     gAppleTalkVersion = GetGestaltResult (gestaltAppleTalkVersion);
  1073.     
  1074.     /* We only concern ourselves with there being an PMMU, not which type it is */
  1075.     gHasPMMU = GetGestaltResult (gestaltMMUType) >= gestalt68851;
  1076.     gAUXVersion = GetAUXVersion ();
  1077.  
  1078.     gHasWaitNextEvent = TrapExists(_WaitNextEvent);
  1079.     gInBackground = false;
  1080.     
  1081. /* 
  1082. 10/16/90 pvh/MacDTS
  1083. With GetAppParams(), THINK C in project mode returns the project resource file AND NOT 
  1084. the .rsrc file, which is what one really wants (trust me).  If THINK is present we will 
  1085. return CurResFile() which will be the .rsrc file instead.  The name will still be the 
  1086. project name in project mode, so be aware of that.
  1087. */
  1088.     GetAppParms(gAppName, &gAppResRef, &apParam);
  1089. #ifdef THINK_C
  1090.     gAppResRef = CurResFile();            /* returns refNum of .rsrc file */
  1091. #endif
  1092.  
  1093.     bndlResource = GetAppIndResource('BNDL', 1, &err);
  1094.     if (bndlResource)
  1095.         gSignature = *(OSType *) (*bndlResource);
  1096.  
  1097.     gUtilitiesInited = true;
  1098. }
  1099.  
  1100.  
  1101.  
  1102. /*****************************************************************************/
  1103.  
  1104.  
  1105.  
  1106. /* Check to see if a window belongs to the application.  If the window pointer
  1107. ** passed was NULL, then it could not be an application window.  WindowKinds
  1108. ** that are negative belong to the system and windowKinds less than userKind
  1109. ** are reserved by Apple except for windowKinds equal to dialogKind, which
  1110. ** mean it is a dialog. */  
  1111.  
  1112. #pragma segment UtilMain
  1113. Boolean    IsAppWindow(WindowPtr window)
  1114. {
  1115.     if (window)
  1116.         return (((WindowPeek)window)->windowKind >= userKind);
  1117.     else 
  1118.         return false;
  1119.  
  1120. }
  1121.  
  1122.  
  1123.  
  1124. /*****************************************************************************/
  1125.  
  1126.  
  1127.  
  1128. /* Check to see if a window belongs to a desk accessory. */
  1129.  
  1130. #pragma segment UtilMain
  1131. Boolean    IsDAWindow(WindowPtr window)
  1132. {
  1133.     if (window)    /* DA windows have negative windowKinds */
  1134.         return (((WindowPeek) window)->windowKind < 0);
  1135.     else
  1136.         return false;
  1137. }
  1138.  
  1139.  
  1140.  
  1141. /*****************************************************************************/
  1142.  
  1143.  
  1144.  
  1145. #pragma segment UtilMain
  1146. void    LocalToGlobalRect(Rect *aRect)
  1147. {
  1148.     LocalToGlobal(&TopLeft(*aRect));
  1149.     LocalToGlobal(&BotRight(*aRect));
  1150. }
  1151.  
  1152.  
  1153.  
  1154. /*****************************************************************************/
  1155.  
  1156.  
  1157.  
  1158. #pragma segment UtilMain
  1159. char    LockHandleHigh(Handle theHandle)
  1160. {
  1161.     char    hstate;
  1162.  
  1163.     hstate = HGetState(theHandle);
  1164.     MoveHHi(theHandle);
  1165.     HLock(theHandle);
  1166.     return(hstate);
  1167. }
  1168.  
  1169.  
  1170.  
  1171. /*****************************************************************************/
  1172.  
  1173.  
  1174.  
  1175. /* InitGraf is always implemented (trap $A86E).  If the trap table is big
  1176. ** enough, trap $AA6E will always point to either Unimplemented or some other
  1177. ** trap, but will never be the same as InitGraf.  Thus, you can check the size
  1178. ** of the trap table by asking if the address of trap $A86E is the same as
  1179. ** $AA6E. */
  1180.  
  1181. #pragma segment UtilInit
  1182. short    NumToolboxTraps(void)
  1183. {
  1184.     if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
  1185.         return (0x200);
  1186.     else
  1187.         return (0x400);
  1188. }
  1189.  
  1190.  
  1191.  
  1192. /*****************************************************************************/
  1193.  
  1194.  
  1195.  
  1196. /* Given any control handle, this will draw an outline around it.  This is used
  1197. ** for the default button of a window.  The extra nice feature here is that
  1198. ** I’ll erase the outline for buttons that are inactive.  Seems like there
  1199. ** should be a Toolbox call for getting a control’s hilite state.  Since there
  1200. ** isn’t, I have to look into the control record myself.  This should be called
  1201. ** for update and activate events.
  1202. **
  1203. ** The method for determining the oval diameters for the roundrect is a little
  1204. ** different than that recommended by Inside Mac. IM I-407 suggests that you
  1205. ** use a hardcoded (16,16) for the diameters.  However, this only looks good
  1206. ** for small roundrects.  For larger ones, the outline doesn’t follow the inner
  1207. ** roundrect because the CDEF for simple buttons doesn’t use (16,16).  Instead,
  1208. ** it uses half the height of the button as the diameter.  By using this
  1209. ** formula, too, our outlines look better.
  1210. **
  1211. ** WARNING: This will set the current port to the control’s window. */
  1212.  
  1213. #pragma segment UtilMain
  1214. void    OutlineControl(ControlHandle button)
  1215. {
  1216.     Rect        theRect;
  1217.     PenState    curPen;
  1218.     short        buttonOval;
  1219.  
  1220.     if (button) {
  1221.         SetPort((*button)->contrlOwner);
  1222.         GetPenState(&curPen);
  1223.         PenNormal();
  1224.         theRect = (*button)->contrlRect;
  1225.         InsetRect(&theRect, kButtonFrameInset, kButtonFrameInset);
  1226.         buttonOval = (theRect.bottom - theRect.top) / 2 + 2;
  1227.  
  1228.         PenPat((*button)->contrlHilite == kCntlActivate ? &QD(black) : &QD(gray));
  1229.  
  1230.         PenSize(kButtonFrameSize, kButtonFrameSize);
  1231.         FrameRoundRect(&theRect, buttonOval, buttonOval);
  1232.         SetPenState(&curPen);
  1233.     }
  1234. }
  1235.  
  1236.  
  1237.  
  1238. /*****************************************************************************/
  1239.  
  1240.  
  1241.  
  1242. #pragma segment UtilMain
  1243. void    OutlineDialogItem(DialogPtr dlgPtr, short item)
  1244. {
  1245.     short iKind;
  1246.     Handle iHandle;
  1247.     Rect iRect;
  1248.  
  1249.     GetDialogItem (dlgPtr, item, &iKind, &iHandle, &iRect);
  1250.     OutlineControl((ControlHandle) iHandle);
  1251. }
  1252.  
  1253.  
  1254.  
  1255. /*****************************************************************************/
  1256.  
  1257.  
  1258.  
  1259. /* Given two rectangles, this function positions the second within the first
  1260. ** one so that it maintains the spacing specified by the horzRatio and
  1261. ** vertRatio parameters.  In other words, to center an inner rectangle
  1262. ** hoizontally, but have its center be 1/3 from the top of the outer rectangle,
  1263. ** call this function with horzRatio = FixRatio (1, 2), vertRatio =
  1264. ** FixRatio(1, 3).  We use Fixed rather than floating point to avoid
  1265. ** complications when mixing MC68881/non-MC68881 versions of Utilities. */
  1266.  
  1267. #pragma segment UtilMain
  1268. void    PositionRectInRect(Rect outerRect, Rect *innerRect, Fixed horzRatio, Fixed vertRatio)
  1269. {
  1270.     short        outerRectHeight;
  1271.     short        outerRectWidth;
  1272.     short        innerRectHeight;
  1273.     short        innerRectWidth;
  1274.     short        yLocation;
  1275.     short        xLocation;
  1276.  
  1277.     outerRectHeight = outerRect.bottom - outerRect.top;
  1278.     outerRectWidth = outerRect.right - outerRect.left;
  1279.  
  1280.     innerRectHeight = innerRect->bottom - innerRect->top;
  1281.     innerRectWidth = innerRect->right - innerRect->left;
  1282.         yLocation = Fix2Long(FixMul(Long2Fix(outerRectHeight - innerRectHeight), vertRatio))
  1283.             + outerRect.top;
  1284.         xLocation = Fix2Long(FixMul(Long2Fix(outerRectWidth - innerRectWidth), horzRatio))
  1285.             + outerRect.left;
  1286.  
  1287.     innerRect->top = yLocation;
  1288.     innerRect->left = xLocation;
  1289.     innerRect->bottom = yLocation + innerRectHeight;
  1290.     innerRect->right = xLocation + innerRectWidth;
  1291. }
  1292.  
  1293.  
  1294.  
  1295. /*****************************************************************************/
  1296.  
  1297.  
  1298.  
  1299. /* Concatenate a Pascal string onto another. */
  1300.  
  1301. #pragma segment UtilMain
  1302. void    PStrConcat(Str255 targetStr, Str255 appendStr)
  1303. {
  1304.     long appendLen;
  1305.  
  1306.     /* Figure out number of bytes to copy, up to 255 */
  1307.     if ((Length (targetStr) + Length (appendStr)) > 255)
  1308.         appendLen = 255 - Length (targetStr);
  1309.     else
  1310.         appendLen = Length (appendStr);
  1311.  
  1312.     if (appendLen > 0) {
  1313.         BlockMove (appendStr + 1, targetStr + Length (targetStr) + 1, appendLen);
  1314.         targetStr [0] += appendLen;
  1315.     }
  1316. }
  1317.  
  1318.  
  1319.  
  1320. /*****************************************************************************/
  1321.  
  1322.  
  1323.  
  1324. #pragma segment UtilInit
  1325. void    PullApplicationToFront(void)
  1326. {
  1327. #define kBroughtToFront 3
  1328.  
  1329.     EventRecord event;
  1330.     short        count;
  1331.  
  1332.     for (count = 1; count <= kBroughtToFront; count++)
  1333.         EventAvail(everyEvent, &event);
  1334. }
  1335.  
  1336.  
  1337.  
  1338. /*****************************************************************************/
  1339.  
  1340.  
  1341.  
  1342. /* Given the button control handle, this will cause the button to look as if it
  1343. ** has been clicked in.  This is nice to do for the user if they type return or
  1344. ** enter to select the default item. */
  1345.  
  1346. #pragma segment UtilMain
  1347. void    SelectButton(ControlHandle button)
  1348. {
  1349.     long            finalTicks;
  1350.     
  1351.     HiliteControl(button, kSelect);
  1352.     Delay(kDelayTime, &finalTicks);
  1353.     HiliteControl(button, kDeselect);
  1354. }
  1355.  
  1356.  
  1357.  
  1358. /*****************************************************************************/
  1359.  
  1360.  
  1361.  
  1362. /* Handy function for setting the value of a radio button.  Given a dialog
  1363. ** pointer, and item number, and a state, this function will take care of the
  1364. ** rest. */
  1365.  
  1366. #pragma segment UtilMain
  1367. void    SetCheckOrRadioButton(DialogPtr dlgPtr, short itemNo, short state)
  1368. {
  1369.     short    iKind;
  1370.     Handle    iHandle;
  1371.     Rect    iRect;
  1372.  
  1373.     GetDialogItem(dlgPtr, itemNo, &iKind, &iHandle, &iRect);
  1374.     SetControlValue((ControlHandle) iHandle, state);
  1375. }
  1376.  
  1377.  
  1378.  
  1379. /*****************************************************************************/
  1380.  
  1381.  
  1382.  
  1383. /* This algorithm for staggering windows does quite a good job.  It also is
  1384. ** quite gnarly.  Here's the deal:
  1385. ** There are pre-designated positions that we will try when positioning a
  1386. ** window.  These slots will be tried from the upper-left corner towards the
  1387. ** lower-right corner.  If there are other windows in that slot, then we will
  1388. ** consider that slot taken, and proceed to the next slot.  A slot is
  1389. ** determined to be taken by checking a point with a slop area.  This slop
  1390. ** area is diamond-shaped, not simply rectangular.  If there is no other
  1391. ** visible window with an upper-left corner within the slopt diamond, then
  1392. ** we are allowed to position our window there.
  1393. ** The above rule holds true unless this forces the window to be partly
  1394. ** off the screen.  If the window ends up partly off the screen, then we try
  1395. ** a new diagonal just below the first diagonal we tried.  We keep trying
  1396. ** lower and lower diagonals until we find a spot for the window, or the
  1397. ** diagonal doesn't fit on the screen at all.  If the diagonal doesn't fit,
  1398. ** then we try diagonals to the right of the first diagonal.  If even this
  1399. ** doesn't work, then we give up and put the window in the original spot
  1400. ** we tried. */
  1401.  
  1402. #pragma segment UtilMain
  1403. Rect    StaggerWindow(WindowPtr window, WindowPtr relatedWindow)
  1404. {
  1405.     WindowPtr    whichDevice, staggerFromWindow;
  1406.     Rect        deviceRect, oldWindowRect, newWindowRect, slot1;
  1407.     Rect        testRect, contentRect, staggerFromRect;
  1408.     Point        delta, absdelta;
  1409.     Boolean        contained, vertTry;
  1410.     short        diamondSize, diagNum, tryNum;
  1411.  
  1412.     if (!(whichDevice = relatedWindow)) whichDevice = window;
  1413.         /* If we have a window to stagger from, use the device for that window,
  1414.         ** else use the device for the window that is getting staggered. */
  1415.  
  1416.     deviceRect = GetWindowDeviceRectNMB(whichDevice);
  1417.         /* We now have the rect of the device we want to stagger within. */
  1418.  
  1419.     oldWindowRect = GetWindowStructureRect(window);
  1420.     newWindowRect.top    = deviceRect.top  + kStartPtV;
  1421.     newWindowRect.left   = deviceRect.left + kStartPtH;
  1422.     newWindowRect.bottom = newWindowRect.top  + oldWindowRect.bottom - oldWindowRect.top;
  1423.     newWindowRect.right  = newWindowRect.left + oldWindowRect.right  - oldWindowRect.left;
  1424.         /* We now have a new rect for the first window position slot. */
  1425.  
  1426.     slot1 = newWindowRect;
  1427.         /* We keep this slot in case we find no acceptable slots.  If we
  1428.         ** don't find an acceptable one, we will use this one anyway. */
  1429.  
  1430.     diamondSize = (kStaggerH < kStaggerV) ? kStaggerH : kStaggerV;
  1431.     for (diagNum = 0, vertTry = true;;) {
  1432.         for (tryNum = 0;; ++tryNum) {
  1433.  
  1434.             SectRect(&newWindowRect, &deviceRect, &testRect);
  1435.             if (!(contained = EqualRect(&newWindowRect, &testRect))) break;
  1436.                 /* Break if the slot we are testing went off the device. */
  1437.  
  1438.             for (staggerFromWindow = FrontWindow();
  1439.                  staggerFromWindow;
  1440.                  staggerFromWindow =
  1441.                     (WindowPtr)((WindowPeek)staggerFromWindow)->nextWindow
  1442.             ) {
  1443.                 if (!((WindowPeek)staggerFromWindow)->visible) continue;
  1444.                     /* This window is invisible.  Staggering from an invisible
  1445.                     ** window is going to confuse the user, so don't do it. */
  1446.  
  1447.                 testRect = GetWindowDeviceRectNMB(staggerFromWindow);
  1448.                 if (!EqualRect(&testRect, &deviceRect)) continue;
  1449.                     /* This window doesn't belong to the device we are trying to
  1450.                     ** stagger on, so skip it and go to the next window. */
  1451.  
  1452.                 staggerFromRect = GetWindowStructureRect(staggerFromWindow);
  1453.                 delta.v = staggerFromRect.top  - newWindowRect.top;
  1454.                 delta.h = staggerFromRect.left - newWindowRect.left;
  1455.                 if ((absdelta.v = delta.v) < 0) absdelta.v = -delta.v;
  1456.                 if ((absdelta.h = delta.h) < 0) absdelta.h = -delta.h;
  1457.                 if ((absdelta.h + absdelta.v) < diamondSize) {
  1458.                     if ((delta.h + delta.v) > 0)
  1459.                         OffsetRect(&newWindowRect, delta.h, delta.v);
  1460.                             /* If the window that took our slot is closer to
  1461.                             ** the lower-right corner than we are, then use
  1462.                             ** this window's location as the basis for the
  1463.                             ** slots from now on.  This will align new windows
  1464.                             ** with previous windows that are not gridded to
  1465.                             ** the default slot positions.  The check for > 0
  1466.                             ** is necessary to prevent bouncing between two
  1467.                             ** existing windows.  This check guarantees that
  1468.                             ** we are progressing with the evaluation. */
  1469.                     break;
  1470.                         /* Break because this slot is already used. */    
  1471.                 }
  1472.             }
  1473.  
  1474.             if (!staggerFromWindow) break;
  1475.                 /* If the window pointer is NULL, then we tried all the windows
  1476.                 ** and none of them occupied this slot.  This means that the
  1477.                 ** slot is available for the new window. */
  1478.  
  1479.                 OffsetRect(&newWindowRect, kStaggerH, kStaggerV);
  1480.                 /* Since this slot was taken, try the next slot and go through
  1481.                 ** the window list again. */
  1482.         }
  1483.  
  1484.         if (contained) break;
  1485.         newWindowRect = slot1;
  1486.         if (!tryNum) {
  1487.             if (!vertTry) break;        /* Nothing works.  No spots at all. */
  1488.             vertTry = false;            /* Try across for the next pass. */
  1489.             diagNum = 0;
  1490.         }
  1491.         ++diagNum;
  1492.         if (vertTry) OffsetRect(&newWindowRect, 0, diagNum * kStaggerV);
  1493.         else         OffsetRect(&newWindowRect, diagNum * kStaggerH, 0);
  1494.     }
  1495.  
  1496.     contentRect = GetWindowContentRect(window);
  1497.         /* Get where the window is now. */
  1498.  
  1499.     OffsetRect(&contentRect, newWindowRect.left - oldWindowRect.left,
  1500.                             newWindowRect.top  - oldWindowRect.top);
  1501.         /* Calculate the new content rect. */
  1502.  
  1503.     MoveWindow(window, contentRect.left, contentRect.top, false);
  1504.         /* Move the window to the new location. */
  1505.  
  1506.     return(contentRect);
  1507. }
  1508.  
  1509.  
  1510.  
  1511. /*****************************************************************************/
  1512.  
  1513.  
  1514.  
  1515. #pragma segment UtilMain
  1516. void    StandardAbout(short appNameStringID)
  1517. {
  1518.     StringHandle    apNameHndl;
  1519.     VersRecHndl        curVersion;
  1520.     Str255            apName;
  1521.     Str255            verNum = "\p????";
  1522.     Ptr                verNumLocation;
  1523.     OSErr            err;
  1524.  
  1525.     if (!gUtilitiesInited)                /* Make sure we were initialized */
  1526.         InitUtilities();
  1527.         
  1528.     apNameHndl = (StringHandle)NULL;
  1529.     if (appNameStringID != kUseRealAppName) {
  1530.         if (appNameStringID != kUseCreatorString)
  1531.             apNameHndl = GetString(appNameStringID);
  1532.         if (!apNameHndl)
  1533.             apNameHndl = (StringHandle) GetAppResource(gSignature, 0, &err);
  1534.     }
  1535.  
  1536.     if ((!apNameHndl) || (appNameStringID == kUseRealAppName))
  1537.         PStrCopy(apName, gAppName);
  1538.     else
  1539.         PStrCopy(apName, *apNameHndl);
  1540.  
  1541.     curVersion = (VersRecHndl) GetAppResource('vers', 1, &err);
  1542.     if (curVersion) {
  1543.         verNumLocation = (Ptr) ((long)(*curVersion)->shortVersion
  1544.                         + (long)*(*curVersion)->shortVersion + 1);
  1545.         PStrCopy(verNum, verNumLocation);
  1546.     }
  1547.  
  1548.     ParamText(apName, verNum, "\p", "\p");
  1549.  
  1550.     CenteredAlert(rStdAboutAlert, NULL);
  1551. }
  1552.  
  1553.  
  1554.  
  1555. /*****************************************************************************/
  1556.  
  1557.  
  1558.  
  1559. #pragma segment UtilInit
  1560. void    StandardInitialization(short callsToMoreMasters)
  1561. {
  1562.     InitToolBox();
  1563.  
  1564.     while (callsToMoreMasters--)
  1565.         MoreMasters();
  1566.     
  1567.     PullApplicationToFront();
  1568.     
  1569.     InitUtilities();
  1570. }
  1571.  
  1572.  
  1573.  
  1574. /*****************************************************************************/
  1575.  
  1576.  
  1577.  
  1578. #pragma segment UtilInit
  1579. void    StandardMenuSetup(short MBARID, short AppleMenuID)
  1580. {
  1581.     Handle menuBar = GetNewMBar(MBARID);            /* read menus into menu bar */
  1582.     if (!menuBar) 
  1583.         DeathAlert(rUtilStrings, eNoMenuBar);
  1584.     SetMenuBar(menuBar);                            /* install menus */
  1585.     DisposeHandle(menuBar);
  1586.     AppendResMenu(GetMenuHandle(AppleMenuID), 'DRVR');    /* add DA names to Apple menu */
  1587.     DrawMenuBar();
  1588. }
  1589.  
  1590.  
  1591.  
  1592. /*****************************************************************************/
  1593.  
  1594.  
  1595.  
  1596. #pragma segment UtilMain
  1597. void    ToggleCheck(DialogPtr dlgPtr, short chkItem)
  1598. {
  1599.     short iKind;
  1600.     Handle iHandle;
  1601.     Rect iRect;
  1602.  
  1603.     GetDialogItem (dlgPtr, chkItem, &iKind, &iHandle, &iRect);
  1604.     SetControlValue((ControlHandle) iHandle, !GetControlValue((ControlHandle)iHandle));
  1605. }
  1606.  
  1607.  
  1608.  
  1609. /*****************************************************************************/
  1610.  
  1611.  
  1612.  
  1613. /* Check to see if a given trap is implemented.  This is only used by the
  1614. ** Initialize function in this program, so we put it in the
  1615. ** Initialize segment. */ 
  1616.  
  1617. #pragma segment UtilInit
  1618. Boolean TrapExists(short theTrap)
  1619. {
  1620.     TrapType    theTrapType;
  1621.  
  1622.     theTrapType = GetTrapType(theTrap);
  1623.     if ((theTrapType == ToolTrap) && ((theTrap &= 0x07FF) >= NumToolboxTraps()))
  1624.         theTrap = _Unimplemented;
  1625.  
  1626.     return (NGetTrapAddress(_Unimplemented, ToolTrap) != NGetTrapAddress(theTrap,
  1627.                   theTrapType));
  1628. }
  1629.  
  1630.  
  1631.  
  1632. /*****************************************************************************/
  1633.  
  1634.  
  1635.  
  1636. /* Zoom the window to the size appropriate for the device that contains the
  1637. ** most of the window.  An additional feature is that you can state the
  1638. ** maximum that a window should be zoomed, either horizontally or vertically.
  1639. ** If you pass in a maximum of 0 for the zoom for either direction, then that
  1640. ** direction will be zoomed to fit the device. */
  1641.  
  1642. #pragma segment UtilMain
  1643. void    ZoomToWindowDevice(WindowPtr window, short maxWidth, short maxHeight,
  1644.                            short zoomDir, Boolean front)
  1645. {
  1646.      GrafPtr        oldPort;
  1647.     Rect        contentRect, structureRect, deviceRect, newRect;
  1648.     short        width, height, dx, dy;
  1649.  
  1650.     GetPort(&oldPort);
  1651.     SetPort(window);
  1652.     EraseRect(&window->portRect);         /* Recommended for cosmetic reasons. */
  1653.  
  1654.     /* If there is the possibility of multiple gDevices, then we must check them to
  1655.     ** make sure we are zooming onto the right display device when zooming out. */
  1656.  
  1657.     if ((zoomDir == inZoomOut) && (gQDVersion > kQDOriginal)) {
  1658.  
  1659.         contentRect      = GetWindowContentRect(window);
  1660.         structureRect = GetWindowStructureRect(window);
  1661.         deviceRect      = GetWindowDeviceRectNMB(window);
  1662.  
  1663.         deviceRect.left   += (contentRect.left - structureRect.left + 2);
  1664.         deviceRect.top    += (contentRect.top - structureRect.top + 2);
  1665.         deviceRect.right  -= (structureRect.right - contentRect.right + 2);
  1666.         deviceRect.bottom -= (structureRect.bottom - contentRect.bottom + 2);
  1667.         newRect = deviceRect;
  1668.  
  1669.         if (maxWidth)
  1670.             if ((width = deviceRect.right - deviceRect.left) > maxWidth)
  1671.                 newRect.right = (newRect.left = contentRect.left) + maxWidth;
  1672.         if (maxHeight)
  1673.             if ((height = deviceRect.bottom - deviceRect.top) > maxHeight)
  1674.                 newRect.bottom = (newRect.top = contentRect.top) + maxHeight;
  1675.         if ((dx = deviceRect.left - newRect.left) < 0)
  1676.             if ((dx = deviceRect.right - newRect.right) > 0)
  1677.                 dx = 0;
  1678.         if ((dy = deviceRect.top - newRect.top) < 0)
  1679.             if ((dy = deviceRect.bottom - newRect.bottom) > 0)
  1680.                 dy = 0;
  1681.         OffsetRect(&newRect, dx, dy);
  1682.  
  1683.         (*(WStateDataHandle)(((WindowPeek)window)->dataHandle))->stdState = newRect;
  1684.             /* Set up the WStateData record for this window. */
  1685.     }
  1686.  
  1687.     ZoomWindow(window, zoomDir, front);
  1688.     SetPort(oldPort);
  1689. }
  1690.  
  1691.  
  1692.  
  1693.